#include "..\GameplayStates\GameplayState.h"
#include "../GameplayStates/MainMenuState.h"
#include "../GameplayStates/LevelState.h"
#include "Player.h"
#include "../Abilities/Spin.h"
#include "Game.h"
CGameplayState* CGameplayState::GetInstance(void)
{
	static CGameplayState s_Instance;
	return &s_Instance;
}

CGameplayState::CGameplayState(void)
{
	this->m_nHealthCostImgID = -1;
	this->m_nLifeBarFrameImgID = -1;
	this->m_nLifeBarImgID = -1;
}

CGameplayState::~CGameplayState(void)
{
}

void CGameplayState::Enter(void)
{
	this->m_pD3D = CSGD_Direct3D::GetInstance();
	this->m_pDI = CSGD_DirectInput::GetInstance();
	this->m_pES = CEventSystem::GetInstance();
	this->m_pMS = CMessageSystem::GetInstance();
	this->m_pOF = CObjectFact::GetInstance();
	this->m_pOM = CObjectManager::GetInstance();
	this->m_pTM = CSGD_TextureManager::GetInstance();
	this->m_pXA = CSGD_XAudio2::GetInstance();
	m_pOF->RegisterClassType<CEntity>(L"CEntity");
	m_pOF->RegisterClassType<CPlayer>(L"CPlayer");
	m_pOF->RegisterClassType<CSpin>(L"CSpin");
	this->m_pPlayer = m_pOF->CreateObject(L"CPlayer");
	this->m_pSpin = m_pOF->CreateObject(L"CSpin");
	this->m_nLifeBarImgID = m_pTM->LoadTexture(L"../resources/graphics/HealthBarFill.jpg", D3DCOLOR_XRGB(255, 255, 255));
	this->m_nLifeBarFrameImgID = m_pTM->LoadTexture(L"../resources/graphics/HealthBarFrame.png", D3DCOLOR_XRGB(255, 255, 255));
	this->m_nHealthCostImgID = m_pTM->LoadTexture(L"../resources/graphics/LifelossBar.png", D3DCOLOR_XRGB(255, 255, 255));
	CPlayer* pPlayer = dynamic_cast<CPlayer*>(m_pPlayer);
	m_pOM->AddObject(pPlayer);
}

void CGameplayState::Exit(void)
{
	if(this->m_pPlayer)
	{
		this->m_pPlayer->Release();
		this->m_pPlayer = nullptr;
	}
	
	if(this->m_pSpin)
	{
		this->m_pSpin->Release();
		this->m_pSpin = nullptr;
	}

	if(this->m_pES)
	{
		this->m_pES->ShutdownEventSystem();
		this->m_pES = nullptr;
	}

	if(this->m_pMS)
	{
		this->m_pMS->ShutdownMessageSystem();
		this->m_pMS = nullptr;
	}
	
	if(this->m_pOF)
	{
		this->m_pOF->ShutDownObjectFactoy();
		this->m_pOF = nullptr;
	}
	
	if(this->m_pOM)
	{
		this->m_pOM->RemoveEVERYTHING();
		this->m_pOM->DeleteInstance();
		this->m_pOM = nullptr;
	}
	if(this->m_nHealthCostImgID != -1)
	{
		this->m_pTM->UnloadTexture(this->m_nHealthCostImgID);
		this->m_nHealthCostImgID = -1;
	}
	if(this->m_nLifeBarFrameImgID != -1)
	{
		this->m_pTM->UnloadTexture(this->m_nLifeBarFrameImgID);
		this->m_nLifeBarFrameImgID = -1;
	}
	if(this->m_nLifeBarImgID != -1)
	{
		this->m_pTM->UnloadTexture(this->m_nLifeBarImgID);
		this->m_nLifeBarImgID = -1;
	}
}

bool CGameplayState::Input(void)
{
	if(m_pDI->KeyPressed(DIK_ESCAPE))
	{
		CGame::GetInstance()->RemoveState(this);
		CGame::GetInstance()->RemoveState(CLevelState::GetInstance());
		CGame::GetInstance()->AddState(CMainMenuState::GetInstance());
	}
	if(this->m_pPlayer)
	{
		CPlayer* pPlayer = dynamic_cast<CPlayer*>(m_pPlayer);
		if(m_pDI->KeyPressed(DIK_SPACE) && pPlayer->GetPosY() + pPlayer->GetHeight() == CGame::GetInstance()->GetHeight() || m_pDI->KeyPressed(DIK_SPACE) &&
			pPlayer->OnPlatform() || pPlayer->OnEnemy())
		{
			//set jumping animation
			pPlayer->SetVelY(-750);
			pPlayer->OnPlatform(false);
			pPlayer->OnEnemy(false);
		}
		if(m_pDI->KeyDown(DIK_LEFT))
		{	
			pPlayer->SetVelX(-300);
			pPlayer->OnPlatform(false);
			pPlayer->OnEnemy(false);
		}
		else if(m_pDI->KeyDown(DIK_RIGHT))
		{
			pPlayer->SetVelX(300);
			pPlayer->OnPlatform(false);
			pPlayer->OnEnemy(false);
		}
		else
		{
			pPlayer->SetVelX(0);
		}
		if(m_pDI->KeyPressed(DIK_Q))
		{
			//This is where the first ability code will go
			CSpin* pSpin = dynamic_cast<CSpin*>(this->m_pSpin);
			pSpin->Init();
			pPlayer->AddAbility(pSpin);
			pPlayer->UpdateTimeLeft();
			spinTimer = 3.0f;
			this->m_fMaxAbilityTime = 3.0f;
			pPlayer->SetSpin(true);
		}
	}
	return true;
}

void CGameplayState::Update(float fElapsedTime)
{
	CPlayer* pPlayer = dynamic_cast<CPlayer*>(m_pPlayer);
	CGame* pGame = CGame::GetInstance();
	if((int)pPlayer->GetPosX() >= m_pCam.camPosX + pGame->GetWidth()/2)
		m_pCam.camPosX = (int)pPlayer->GetPosX() - pGame->GetWidth()/2;
	if(spinTimer > 0.0f)
		spinTimer -= fElapsedTime;
	else
	{
		pPlayer->SetSpin(false);
	}
	m_fPlayerHealthScale = (float)pPlayer->GetHealth() / (float)pPlayer->GetMaxHealth();
	m_fLifeLossScale = (float)pPlayer->GetPotLifeLoss() / (float)pPlayer->GetMaxHealth();
	m_pOM->UpdateEVERYTHING(fElapsedTime);
	m_pOM->CheckCollisions();
	if(pPlayer->GetSpin())
	{
		//if(spinTimer < 3.0f && spinTimer > 2.0f)
			//Do something for spin
		//if(spinTimer < 2.0f && spinTimer > 1.0f)
			//Do something for spin
		//if(spinTimer < 1.0f && spinTimer > 0.0f)
			//Do something for spin
	}
}

void CGameplayState::Render(void)
{
	m_pTM->Draw(this->m_nLifeBarImgID, 0, 0, m_fPlayerHealthScale, 1.0f, 0);
	m_pTM->Draw(this->m_nLifeBarFrameImgID, 0, 0, 1.0f, 1.0f, 0);
	CPlayer* pPlayer = dynamic_cast<CPlayer*>(m_pPlayer);
	float sPos = (float)pPlayer->GetHealth() - (float)pPlayer->GetPotLifeLoss();
	sPos = sPos / 100.0f * 256.0f;
	float sPos2 = pPlayer->GetTimeLeft() - m_fMaxAbilityTime;
	sPos2 = sPos2 / 100.0f * 278.0f;

	if(pPlayer->GetPotLifeLoss() > 0)
		m_pTM->Draw(this->m_nHealthCostImgID, (int)sPos, 0, m_fLifeLossScale, 1.0f, 0);
	m_pOM->RenderEVERYTHING();

	TCHAR buffer[ 100 ];
	int currentHits = pPlayer->GetCurrentHits();
	_stprintf_s( buffer, 100, _T("Hits: %i"),currentHits);
	m_pD3D->DrawText(buffer, CGame::GetInstance()->GetWidth()-8*16, 15);
	if(pPlayer->GetHitReq() > 0)
	{
		TCHAR buff[100];
		int hitsNeeded = pPlayer->GetHitReq();
		_stprintf_s(buff, 100, _T("/%i"), hitsNeeded);
		m_pD3D->DrawText(buff, CGame::GetInstance()->GetWidth()-8*16 + 48, 15);
	}
	if(pPlayer->GetTimeLeft() > 0)
	{
		TCHAR timeBuff[100];
		int timeLeft = (int)pPlayer->GetTimeLeft();
		_stprintf_s(timeBuff, 100, _T("Time Left: %i seconds"), timeLeft);
		m_pD3D->DrawText(timeBuff, (int)(CGame::GetInstance()->GetWidth()*.5f)-48, 15);
	}
}

void CGameplayState::HandleEvent(CNEvent* pEvent)
{

}